﻿#region Using Statements
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
#endregion

namespace BreakOutBattles.Game.Items
{
    public class FadeBrick : Brick
    {
        #region Fields
        private Rectangle zeroRectangle = new Rectangle(0, 0, 0, 0);
        private int defaultResistance = 10;

        private byte alpha = 0;
        private byte alphaInc = 20;
        private int fadeStepDelay = 100;
        private int fadeStepTime = 0;
        private int activeTime = 3000;
        private int unactiveTime = 5000;
        private int totalTime = 0;
        private bool fadeOut = false;
        private bool fadeIn = false;
        private bool fadeActive = false;
        #endregion

        public FadeBrick(Vector2 location, Texture2D itemTexture)
            : base(location, itemTexture)
        {
            Resistance = defaultResistance;
        }

        /// <summary>
        /// Resets the brick to its default values.
        /// </summary>
        public override void Reset()
        {
            base.Reset();
            Resistance = defaultResistance;
        }

        #region Brick Fading
        /// <summary>
        /// Increases the ammount of texture alpha until it reaches a maximum alpha value.
        /// </summary>
        private void FadeOut(GameTime gameTime)
        {
            fadeStepTime += gameTime.ElapsedGameTime.Milliseconds;

            if (alpha < 255 && fadeStepTime > fadeStepDelay)
            {
                alpha = (byte)MathHelper.Clamp(alpha + alphaInc, 0, byte.MaxValue);
                fadeStepTime = 0;
            }

            if (alpha >= byte.MaxValue)
            {
                fadeOut = false;
                fadeActive = false;
            }
        }

        /// <summary>
        /// Decreases the ammount of texture alpha until it reaches a zero-alpha value.
        /// </summary>
        private void FadeIn(GameTime gameTime)
        {
            fadeStepTime += gameTime.ElapsedGameTime.Milliseconds;

            if (alpha > 0 && fadeStepTime > fadeStepDelay)
            {
                alpha = (byte)MathHelper.Clamp(alpha - alphaInc, 0, byte.MaxValue);
                fadeStepTime = 0;
            }

            if (alpha <= 0)
            {
                fadeIn = false;
                fadeActive = false;
            }
        }

        /// <summary>
        /// Handles the brick texture fading process.
        /// </summary>
        private void Fade(GameTime gameTime)
        {
            //The brick is not visible to the player, keep it unactive for a while.
            if (alpha <= 0 && totalTime <= unactiveTime)
            {
                totalTime += gameTime.ElapsedGameTime.Milliseconds;
            }

            //The brick is not visble to the player, but its maximum unactive time is reached.
            if (alpha <= 0 && totalTime >= unactiveTime)
            {
                fadeOut = true;
                fadeActive = true;
                totalTime = 0;
            }

            //The brick is visible to the player, keep it active for a while.
            if (alpha >= byte.MaxValue && totalTime <= activeTime)
            {
                totalTime += gameTime.ElapsedGameTime.Milliseconds;
            }

            //The brick is visible to the player, but its maximum active time is reached.
            if (alpha >= byte.MaxValue && totalTime >= activeTime)
            {
                fadeIn = true;
                fadeActive = true;
                totalTime = 0;
            }

            if (fadeActive && fadeOut)
            {
                FadeOut(gameTime);
            }

            if (fadeActive && fadeIn)
            {
                FadeIn(gameTime);
            }
        }
        #endregion

        /// <summary>
        /// Gets a Rectangle that completely covers this brick.
        /// </summary>
        public override Rectangle CollisionRect
        {
            get
            {
                if (alpha <= 0)
                {
                    return zeroRectangle;
                }
                else
                {
                    return base.CollisionRect;
                }
            }
        }

        /// <summary>
        /// Updates the brick.
        /// </summary>
        public override void Update(GameTime gameTime)
        {
            Fade(gameTime);
        }

        /// <summary>
        /// Renders the brick.
        /// </summary>
        public override void Draw(SpriteBatch spriteBatch)
        {
            if (Active && itemTexture != null)
            {
                float alphaFactor = (float)((float)alpha / (float)byte.MaxValue);
                spriteBatch.Draw(itemTexture, currentLocation, Color.White * alphaFactor);
            }
        }
    }
}
